<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>基础vue教程</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
</head>
<body>
    <!-- view视图 -->
    <div id="app">
        <!-- 一、MVVM模式和第一个Vue程序
            1.什么是 MVVM
            该层向上与视图层进行双向数据绑定
            向下与 Model 层通过接口请求进行数据交互
        第一个Vue程序 -->
        <input type="text" v-model="message">
        {{ message }}
        <br>

        <!-- 二、基础语法 -->
        <!-- v-bind就是用于绑定数据和元素属性的 -->
        <!-- 注意：
          v-bind后面是：属性名=，我的理解是表示绑定这个属性，绑定之后，对应的值要去vue的数据里面找。
          当我们在控制台改变url时，对应也会变化。
        相同的，我们还可以绑定图片src属性、超链接的class -->
        <a v-bind:href="url">点我</a>

        <img v-bind:src="imgurl" width="200px">
        <!-- 通常我们可以将v-bind：简写成： -->
        <a :href="url">点我</a>

        <!-- v-if,v-else -->
        <div v-if="ok">YES</div>
        <div v-else>NO</div>

        <!-- v-if,v-else-if,v-else -->
        <div v-if="role=='beixi' || role=='admin'">您好，admin</div>
        <div v-else-if="role == 'zxl'">张鑫磊</div>
        <div v-else>您无权访问！</div>

        <!-- v-for循环普通数组 -->
        <p v-for="(item,index) in list">{{ item }}----索引:{{ index }}</p>
        <!-- v-for循环对象数组 -->
        <p v-for="(user,index) in listtable">{{ user.id }}--{{ user.name }}-----索引:{{index}}</p>
        <!-- v-for循环对象 -->
        <p v-for="(val,key,index) in user">值：{{ val }} ---键{{ key }}-----索引{{ index }}</p>
        <!-- v-for循环数字 -->
        <p v-for="count in 5">这是第{{ count }}次循环</p>

        <!-- 三、Vue绑定事件 -->
        <!-- 语法：
            v-on:事件名 = “方法名”
          简写： @事件名 = “方法名”
          事件名： click|keydown|keyup|mouseover|mouseout|自定义事件名 -->

        <!-- v-on事件监听，完整示例： -->
        <!-- 注意：v-bind可以简写为 ： v-on: 可以简写@ -->
        {{count}}
        <button @click="count+=1">点我加1</button>
        <button v-on:click="sub">点我减1</button>

        <!-- 四、Vue：表单双绑、组件 -->
        <!-- 1.什么是双向数据绑定
          Vue.js 是一个 MVVM 框架，即数据双向绑定，即当数据发生变化的时候，视图也就发生变化，当视图发生变化的时候，数据也会跟着同步变化。这也算是 Vue.js 的精髓之处了。
          值得注意的是，我们所说的数据双向绑定，一定是对于 UI 控件来说的，非 UI 控件不会涉及到数据双向绑定。单向数据绑定是使用状态管理工具的前提。如果我们使用 vuex，那么数据流也是单项的，这时就会和双向数据绑定有冲突。 -->
        <!-- 2.在表单中使用双向数据绑定
        可以用 v-model 指令在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇，但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据，并对一些极端场景进行一些特殊处理。
        注意：v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值! -->
        <input type="radio" name="sex" value="男" v-model="gender">男
        <input type="radio" name="sex" value="女" v-model="gender"/>女
        <p>{{gender}}</p>

        <select  v-model="selected">
            <option value="">--请选择--</option>
            <option value="北京">北京</option>
            <option value="上海">上海</option>
            <option value="广州">广州</option>
        </select>
        <p>{{ selected }}</p>

        <!-- 3.什么是组件 -->
        <!-- 组件是可复用的 Vue 实例，说白了就是一组可以重复使用的模板，跟 JSTL 的自定义标签、Thymeleaf 的 th:fragment 等框架有着异曲同工之妙。 -->
        <!-- 例如，你可能会有页头、侧边栏、内容区等组件，每个组件又包含了其它的像导航链接、博文之类的组件。 -->
        <!-- 4.简单定义一个组件 -->
        <!-- 注意：在实际开发中，我们并不会用以下方式开发组件，而是采用 vue-cli 创建 .vue 模板文件的方式开发，以下方法只是为了让大家理解什么是组件。 -->
        <beixi></beixi>
        <!-- 5.使用 props 属性动态传递参数 -->
        <!--组件：使用props把值传递给组件-->
        <blog-post v-for="item in items" v-bind:value="item"></blog-post>


        <!-- 五、Axios异步通信
        1.什么是Axios
          Axios 是一个开源的可以用在浏览器端和 NodeJS 的异步通信框架，她的主要作用就是实现 AJAX 异步通信，其功能特点如下：

        从浏览器中创建 XMLHttpRequests
        从 node.js 创建 http 请求
        支持 Promise API [JS中链式编程]
        拦截请求和响应
        转换请求数据和响应数据
        取消请求
        自动转换 JSON 数据
        客户端支持防御 XSRF（跨站请求伪造）
          GitHub：https://github.com/axios/axios

          中文文档：http://www.axios-js.com/

        2.为什么要使用 Axios
          由于 Vue.js 是一个 视图层框架 并且作者（尤雨溪）严格准守 SoC （关注度分离原则），所以 Vue.js 并不包含 AJAX 的通信功能，
        为了解决通信问题，作者单独开发了一个名为 vue-resource 的插件，不过在进入 2.0 版本以后停止了对该插件的维护并推荐了 Axios 框架。少用jQuery，因为它操作Dom太频繁！

        3.第一个 Axios 应用程序
          咱们开发的接口大部分都是采用 JSON 格式，可以先在项目里模拟一段 JSON 数据，数据内容如下：创建一个名为 data.json 的文件并填入上面的内容，放在项目的根目录下 -->


        <!-- 六、计算属性 -->
        <!-- computed主要的作用:
          分离逻辑(模板和数据分离)
          缓存值
          双向绑定(getter,setter) -->

        <input type="text" v-model="num1">
        <input type="text" v-model="num2">
        <p>求和结果{{ result }}</p>

        <!-- 3、methods方法与computed计算属性区别
            两者的执行结果是完全相同的
            计算属性是基于他们的依赖进行缓存的，只有在相关依赖发生改变时，
                他们才会重新求值，也就是说，只要他的依赖没有发生变化，那么每次访问的时候计算属性都会立即返回之前的计算结果，不再执行函数
            每次触发重新渲染时，调用方法将总会再次执行函数 -->
    </div>
    <script>
        //注册组件
        // 说明：
        // Vue.component()：注册组件
        // beixi：自定义组件的名字
        // template：组件的模板
        Vue.component("beixi",{
            template:'<li>hellp</li>'
        })
//         说明：
// v-for=“item in items”：遍历 Vue 实例中定义的名为 items 的数组，并创建同等数量的组件
// v-bind:value=“item”：将遍历的 item 项绑定到组件中 props 定义的名为 value属性上；= 号左边的 value 为 props 定义的属性名，右边的为 item in items 中遍历的 item 项的值
        Vue.component("blog-post",{
            props:['value'],
            template:'<li>{{ value }}</li>'             
        })
        // new 一下vue
        var vue = new Vue({
            //绑定元素
            el:'#app',
            /*model数据*/
            data:{
                message:"",
                url:"https://www.baidu.com",
                imgurl:"https://cn.vuejs.org/images/logo.png",
                ok:true,  //false
                role:'admin',
                list:[1,2,3,4,5],
                listtable:[
                    {id:1,name:'beixi'},
                    {id:2,name:'jzj'},
                    {id:3,name:'贾志杰'}
                ],
                user:{
                    name:"beixi",
                    age:"18",
                    sex:"男"
                },
                count:1,
                gender:'',
                selected:'',
                items:['beixi','jzj','贾志杰'],
                num1:1,
                num2:2
            },
            methods: {
                sub:function(){
                    this.count -= 1;
                }
            },
            computed: {//计算属性
                result:function(){
                    return parseInt(this.num1)+parseInt(this.num2);
                }
            },
        })
    </script>
</body>
</html>